package com.adil.base.collections.list;

import java.util.*;

/**
 * @description: 接口的作用
 * @author: Adil
 * @date: 2024/4/24
 */
public class RandomAccessDemo {
//    RandomAccess 接口是一个空接口，只是一个标记接口，用以标记实现的List集合具备快速随机访问的能力。那么什么是随机访问的能力呢？其实很简单，随机访问就是随机的访问List中的任何一个元素。所有的List实现都支持随机访问的，只是基于基本结构的不同，实现的速度不同罢了，这里的快速随机访问，那么就不是所有List集合都支持了。
//    ArrayList：基于数组实现，天然带下标，可以实现常量级的随机访问，复杂度为O(1)。
//    LinkedList：基于链表实现，随机访问需要依靠遍历实现，复杂度为O(n)。
    public static void main(String[] args) {
        // 对于ArrayList来说，fori的遍历速度要快于iterator的遍历，但是对于LinkedList来说，两者的速度差距更大。
        RandomAccessDemo randomAccessDemo = new RandomAccessDemo();
    //  randomAccessDemo.demo1();
        randomAccessDemo.demo2();
        randomAccessDemo.loop(new ArrayList<>());
        randomAccessDemo.loop(new LinkedList<>());

    //  ArrayList用for循环遍历比iterator迭代器遍历快，LinkedList用iterator迭代器遍历比for循环遍历快，所以说，当我们在做项目时，
    //  应该考虑到List集合的不同子类采用不同的遍历方式，能够提高性能！那怎么判断出接收的List子类是ArrayList还是LinkedList呢？
    //  这时就需要用 instanceof 来判断List集合子类是否实现RandomAccess接口！

    }

    public void demo1() {
        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < 500000; i++) {
            arrayList.add(i);
        }
        long s = System.currentTimeMillis();
        for (int i = 0; i < arrayList.size(); i++) {
            Integer integer = arrayList.get(i);
        }
        long e = System.currentTimeMillis();
        System.out.println("实现了RandomAccess的ArrayList采用fori的遍历用时：" + (e - s));
        long s2 = System.currentTimeMillis();
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
        }
        long e2 = System.currentTimeMillis();
        System.out.println("实现了RandomAccess的ArrayList采用iterator的遍历用时：" + (e2 - s2));
//        实现了RandomAccess的ArrayList采用fori的遍历用时：16
//        实现了RandomAccess的ArrayList采用iterator的遍历用时：38
    }

    public void demo2() {
        // 示列2：
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < 50000; i++) {
            linkedList.add(i);
        }
        long s = System.currentTimeMillis();
        for (int i = 0; i < linkedList.size(); i++) {
            Integer integer = linkedList.get(i);
        }
        long e = System.currentTimeMillis();
        System.out.println("没有实现RandomAccess的LinkedList采用fori的遍历用时：" + (e - s));
        long s2 = System.currentTimeMillis();
        Iterator<Integer> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
        }
        long e2 = System.currentTimeMillis();
        System.out.println("没有实现RandomAccess的LinkedList采用iterator的遍历用时：" + (e2 - s2));
//        没有实现RandomAccess的LinkedList采用fori的遍历用时：1150
//        没有实现RandomAccess的LinkedList采用iterator的遍历用时：3
    }

    /**
     * 采用for循环遍历或迭代器遍历List集合
     * @param list
     */
    public void loop(List list) {
        if (list instanceof RandomAccess) {
            // for循环
            System.out.println("采用for循环遍历");
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        } else {
            // 迭代器
            System.out.println("采用迭代器遍历");
            Iterator it = list.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }
        }
    }
}
